/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************/
#include "safewatchdog.h"
//#include <unistd.h>
#include <qthread.h>
//#include "mainwindow.h"
#include "powermanager.h"
//#include "globalfunction.h"
//#include "../GlobalFunction/globalfunction.h"

extern PowerManager *p_powerManger;
void watchDogFailedProcessFunction()
{
    #ifndef D_DISABLE_WATCH_DOG
    p_powerManger->watchDogFailedProcessFunction();
    #endif
}

SafeWatchDog::SafeWatchDog(double maxTimeIntervalIn, double checkTimeIntervalIn, void *classPtrIn, int classIdIn)
{
    maxTimeInterval=maxTimeIntervalIn;
    checkTimeInterval=checkTimeIntervalIn;
    classPtr=classPtrIn;
    classId=classIdIn;
    int i;

    startDogFlag=false;
    createThread();
    qDebug()<<"SafeWatchDog::,SafeWatchDog create success-------------------------";
}

SafeWatchDog::~SafeWatchDog()
{
    if(0==pthread_cancel(threadId))
    {
        qDebug()<<"SafeWatchDog::,~SafeWatchDog, watch dog thread pthread_cancel success-------------------------";
    }
}

int SafeWatchDog::killThread()
{
    if(0==pthread_cancel(threadId))
    {
        qDebug()<<"SafeWatchDog::,killThread success-------------------------";
        return 1;
    }
    else
    {
        return -1;
    }
}

int SafeWatchDog::startDog()
{
    dogState=E_DOG_STATE_NORMAL;
    //struct timespec nowTime;
    clock_gettime(CLOCK_REALTIME, &dogLastTime);
    //dogLastTime=nowTime.tv_sec;
    startDogFlag=true;
//    qDebug()<<"SafeWatchDog::,startDog success-------------------------";
    return 1;
}

int SafeWatchDog::resetDog()
{
    dogState=E_DOG_STATE_NORMAL;
    startDogFlag=false;
    if(0)
    {
            qDebug()<<"SafeWatchDog::,resetDog success-------------------------";
    }

    return 1;
}

int SafeWatchDog::feedDog()
{
    clock_gettime(CLOCK_REALTIME, &dogLastTime);
//    qDebug()<<"SafeWatchDog::,feedDog success-------------------------";
}

long SafeWatchDog::getDogState()
{
    return dogState;
}

long SafeWatchDog::getDogLastFeedTimeLength()
{
    struct timespec nowTime , differenceTime;
    clock_gettime(CLOCK_REALTIME, &nowTime);
    differenceTime.tv_sec=nowTime.tv_sec-dogLastTime.tv_sec;
    differenceTime.tv_nsec=nowTime.tv_nsec-dogLastTime.tv_nsec;
    long tmpLength=differenceTime.tv_sec*1000.0+differenceTime.tv_nsec/1000000.0;
    //qDebug()<<"differenceTime.tv_sec"<<differenceTime.tv_sec<<"(int)differenceTime.tv_sec*1000.0"<<((int)differenceTime.tv_sec)*1000.0;
    //qDebug()<<"(int)differenceTime.tv_sec*1000.0"<<(int)differenceTime.tv_sec*1000.0<<"differenceTime.tv_nsec/1000000.0"<<differenceTime.tv_nsec/1000000.0 ;
//    qDebug()<<"getDogLastFeedTimeLength="<<tmpLength ;
    return tmpLength;
}


#include <unistd.h>
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)
void* SafeWatchDog::threadRun(void *)
{
    printf("SafeWatchDog::,globalManager theread start run !!!");
#if 0
    int max_cpus = sysconf(_SC_NPROCESSORS_ONLN);
    printf("Max CPUs = %d\n", max_cpus);

    /* lock all memory (prevent swapping) */
    if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
        printf("printf: mlockall\n");
    }

    set_latency_target();
    set_cpu(0);
#endif

    struct sched_param param;
    param.__sched_priority = 50;
    sched_setscheduler(0,SCHED_FIFO,&param);
    //setStackSize(81920);
    int policy, priority;
    pthread_getschedparam(pthread_self(), &policy, (struct sched_param *)&priority);
    qDebug()<<"************************SafeWatchDog pid="<<gettid();
    usleep(889000);
//    if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
//        qDebug("mlockall failed");
//    }
//    clock_gettime( CLOCK_MONOTONIC, &cycleTimespec );

   // qDebug()<<"this=="<<this;
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //允许退出线程
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); //设置立即取消
    while(1)
    {
        pthread_testcancel();/*the thread can be killed only here*/
         QThread::msleep(100);
        while(true==startDogFlag && E_DOG_STATE_NORMAL==dogState)
        {
            QThread::msleep(checkTimeInterval);
            if(getDogLastFeedTimeLength()>maxTimeInterval )
            {
                watchDogFailedProcessFunction();
//                switch(classId)
//                {
//                    case 1:
//                    {
//                        qDebug()<<"watch dog failed-------------------------";
////                        ((MainWindow*)classPtr)->watchDogFailedProcess();
//                        break;
//                    }
//                }
                dogState=E_DOG_STATE_FAILED_PROCESSED;
            }

        }
    }
    printf("SafeWatchDog::,watchdog thread quit!!!");
}

void* SafeWatchDog::threadTask( void* classPtr )
{
    qDebug()<<"SafeWatchDog::,thread run-------------------------";
    return ((SafeWatchDog*)classPtr)->threadRun(NULL);
}

void SafeWatchDog::createThread()
{
    int ret=pthread_create( &threadId, NULL, &SafeWatchDog::threadTask,this);
    qDebug()<<"SafeWatchDog::,createThread-------------------------";
}

